package com.act.moudles.act.service.impl;

import com.act.constant.TaskAnoTypeEnums;
import com.act.moudles.act.compents.ActCompent;
import com.act.moudles.act.pojo.TaskRunPojo;
import com.act.moudles.act.service.TaskRunService;
import com.act.moudles.baseAct.dao.TaskAnoDao;
import com.act.moudles.baseAct.dao.TaskAnoVarsDao;
import com.act.moudles.baseAct.entity.TaskAno;
import com.act.moudles.baseAct.entity.TaskAnoPris;
import com.act.moudles.baseAct.entity.TaskAnoVars;
import com.act.moudles.user.entity.User;

import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.impl.identity.Authentication;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

@Service
public class TaskRunServuceImpl implements TaskRunService {


    @Resource
    private TaskService taskService;

    @Resource
    private TaskAnoDao taskAnoDao;

    @Resource
    private TaskAnoVarsDao taskAnoVarsDao;

    /**
     * 运行时服务，可以处理所有正在运行状态的流程实例，任务等
     * 主要用来开启流程实例，一个流程实例对应多个任务，也就是多个流程节点
     */
    @Resource
    private RuntimeService runtimeService;


    @Resource
    private ActCompent actCompent;



    @Override
    public String startFlow(TaskRunPojo pojo,User user) throws Exception {
        //验证
        String flowKey = null;
        try {
            flowKey = actCompent.checkAndToFlowKey(pojo.getUserFlowKey(),user.getTenantId());
        }catch (Exception e){
            e.printStackTrace();
            throw  new RuntimeException(e.getMessage());
        }
        //2.验证变量
        List<String>  shaoVars = new ArrayList<>();
        TaskAno minTask = taskAnoDao.selectminByUserFlowKey(pojo.getUserFlowKey(), TaskAnoTypeEnums.USER_TASK.getTaskType());
        List<TaskAnoVars> varsList =  taskAnoVarsDao.selectByAnoId(minTask.getId());
        for(TaskAnoVars vars : varsList){
            if(pojo.getParamMap().get(vars.getVarKey()) == null || StringUtils.isEmpty( pojo.getParamMap().get(vars.getVarKey()).toString().trim())){
                shaoVars.add(vars.getVarName()+":"+vars.getVarKey());
            }
        }
        if(!CollectionUtils.isEmpty(shaoVars)){
            throw new RuntimeException(String.join(";",shaoVars));
        }

        //3.发起流程
        Authentication.setAuthenticatedUserId(String.valueOf(user.getUserId()));
        ProcessInstance processInstance;
        if(CollectionUtils.isEmpty(pojo.getParamMap())){
            processInstance = runtimeService.startProcessInstanceByKeyAndTenantId(flowKey,user.getTenantId());
        }else {
            processInstance = runtimeService.startProcessInstanceByKeyAndTenantId(flowKey,pojo.getParamMap(),user.getTenantId());
        }
        return processInstance.getProcessInstanceId();
    }



    @Override
    public void compileTask(TaskRunPojo pojo,User user) throws Exception {
        //1.鉴权
        try {
            actCompent.checkAndToFlowKey(pojo.getUserFlowKey(),user.getTenantId());
        }catch (Exception e){
            throw  new RuntimeException(e.getMessage());
        }

        //2.执行任务
        List<Task> taskList = taskService.createTaskQuery().processInstanceId(pojo.getProcId()).taskTenantId(user.getTenantId()).taskAssignee(pojo.getAssgine()).list();
        if(CollectionUtils.isEmpty(taskList)){
            throw  new RuntimeException("流程不存在或者已经结束");
        }
        //3.执行任务(即使同时存在，一次也只需要执行一次)
        Task task = taskList.get(0);
        Map<String,Object>  paramMap = pojo.getParamMap();
        paramMap.put(task.getAssignee(),pojo.getAssgine());
        //批注人的名称  一定要写，不然查看的时候不知道人物信息
        Authentication.setAuthenticatedUserId(user.getUserId().toString());
        if(StringUtils.isNotEmpty(pojo.getComment())){
            taskService.addComment(task.getId(),null, pojo.getComment());
        }
        taskService.complete(task.getId(),paramMap);
    }

  
}
